fix(runtime+frontend): stream codex turns live; SSO-off auth endpoints return JSON#615
Merged
Conversation
The codex runtime called `await thread.run(prompt)`, which blocks until the whole turn (reasoning + tool calls + final message) completes, then emitted all ADK events at once. Over /run_sse this left the client silent for the entire turn — next to adk's live streaming, codex looked frozen for tens of seconds before everything appeared at the end. Consume the Codex turn stream instead (`thread.turn(...).stream()`) and emit ADK events as each item completes, honoring BaseRuntime's async-generator contract truly incrementally. No server/Runner changes — purely the runtime layer, so other runtimes keep the same streaming contract. - translate.py: split result_to_events into a reusable per-item `item_to_events`; result_to_events now composes it (+ keeps the final_response fallback for the batch path). - runtime.py: stream ItemCompletedNotification -> item_to_events; raise on a failed TurnCompletedNotification. Verified: reasoning + tool-call events arrive mid-turn (~7s) instead of all at the end (~16s); thinking renders live.
…config
When SSO is not configured, the SPA still fetches /web/auth-config and
/oauth2/userinfo on startup; those paths fell through to the StaticFiles SPA
fallback and returned the HTML shell, so the app's `await res.json()` threw
("Unexpected token '<'") and it hung on a blank boot screen.
Always register /web/auth-config (empty provider list when SSO is off) and, when
SSO is off, add a /oauth2/userinfo route that returns 401 JSON, so the SPA's
identity check resolves cleanly and renders its normal no-login UI.
Needed for the codex-runtime demo (veadk frontend without SSO) to load.
zakahan
approved these changes
Jun 16, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Two fixes that together make the
runtime="codex"demo work end-to-end inveadk frontend.1. Stream codex turns incrementally (runtime)
The codex runtime called
await thread.run(prompt), which collects the entire turn before returning, then emitted all ADK events at once. Over/run_ssenothing reached the client mid-turn, so (next to adk's live streaming) codex looked frozen for tens of seconds.Fix (runtime layer only — no server/Runner changes): consume the Codex turn stream and emit ADK events as each item completes, honoring
BaseRuntime's async-generator contract.translate.py: splitresult_to_eventsinto a reusable per-itemitem_to_events;result_to_eventscomposes it (+ keeps thefinal_responsefallback).runtime.py:thread.turn(prompt).stream()→ perItemCompletedNotification, yielditem_to_events(item); raise on a failedTurnCompletedNotification.Verified (timestamps per yielded event): reasoning + tool steps now arrive mid-turn (~7s) instead of all at the end (~16s).
2. SSO-off auth endpoints return JSON (frontend server)
With SSO not configured, the SPA still fetches
/web/auth-configand/oauth2/userinfoon startup; both fell through to the StaticFiles SPA fallback and returned the HTML shell, soawait res.json()threw (Unexpected token '<') and the app hung on a blank boot screen.Fix: always register
/web/auth-config(empty providers when SSO off) and, when SSO is off, add/oauth2/userinfo→ 401 JSON, so the SPA's identity check resolves cleanly.Verified end-to-end
veadk frontend --agents-dir examples/force_demo(no SSO) → app loads;codex_runtimeagent streamsTHOUGHTthentextlive over/run_sse.